import json
from tornado.web import RequestHandler
from apps.users.forms import *
from apps.utils.AsyncYunPian import AsyncYunPian
from functools import partial
from datetime import datetime
import jwt
import random
from Forum.handler import RedisHandler
from apps.users.models import User
from apps.utils.decorators import authenticated_async

class SmsHandler(RedisHandler):
    def generate_code(self):
        """
        生成四位数验证码
        :return:
        """
        seeds = "1234567890"
        random_str = []
        for i in range(4):
            random_str.append(random.choices(seeds)[0])
        print(random_str)
        return "".join(random_str)
    async def post(self, *args, **kwargs):
        re_data = {}
        param = self.request.body.decode("utf-8")

        param = json.loads(param)
        print(param)
        sms_form = SmsCodeForm.from_json(param)
        if sms_form.validate():
            print("手机号正确")
            mobile = sms_form.mobile.data

            code = self.generate_code()
            # yun = AsyncYunPian()
            # re_json = await yun.send_single_sms(code, mobile)
            re_json = {"code": 0, "msg":"登录成功"}
            if re_json['code'] != 0:
                print("发送验证码失败")
                self.set_status(400)
                re_data["mobile"] = re_json["msg"]
            else:
                #验证码写入redis
                print("写入redis")
                self.redis_conn.set("{}_{}".format(mobile, code), 1, 10*60)
                pass
        else:
            print("手机号错误")
            self.set_status(400)
            for field in sms_form.errors:
                re_data[field] = sms_form.errors[field][0]

        self.finish(re_data)

class RegisterHandler(RedisHandler):
    async def post(self, *args, **kwargs):
        re_data = {}

        param = self.request.body.decode("utf-8")

        param = json.loads(param)
        print(param)
        register_form = RegisterForm.from_json(param)
        if register_form.validate():
            mobile = register_form.mobile.data
            code = register_form.code.data
            password = register_form.password.data

            #验证码是否正确
            redis_key = "{}_{}".format(mobile, code)
            if not self.redis_conn.get(redis_key):
                print("验证码错误")
                self.set_status(400)
                re_data['code'] = "验证码错误或者失效"
            else:
                print("验证码正确")
                try:
                    existed_users = await self.application.objects.get(User, mobile=mobile)
                    self.set_status(400)
                    re_data['mobile'] = "用户已存在"
                except User.DoesNotExist:
                    user = await self.application.objects.create(User, mobile=mobile,password=password)
                    re_data["id"] = user.id
                    print("创建用户成功")
        else:
            self.set_status(400)
            print("注册表单填写错误")
            for field in register_form.errors:
                re_data[field] = register_form[field][0]
        self.finish(re_data)

class LoginHandler(RedisHandler):
    async def post(self, *args, **kwargs):
        re_data = {}

        param = self.request.body.decode("utf-8")
        param = json.loads(param)
        loginform = LoginForm.from_json(param)
        if loginform.validate():
            mobile = loginform.mobile.data
            password = loginform.password.data
            try:
                user = await self.application.objects.get(User, mobile=mobile)
                if not user.password.check_password(password):
                    self.set_status(400)
                    re_data["non_fields"] = "用户或密码错误"
                else:
                    print("登录成功")
                    payload = {
                        "id": user.id,
                        "nick_name": user.nickname,
                        "exp": datetime.utcnow()
                    }
                    token = jwt.encode(payload, self.settings["secret_key"], algorithm='HS256')
                    re_data["id"] = user.id
                    if user.nickname is not None:
                        re_data["nick_name"] = user.nickname
                    else:
                        re_data["nick_name"] = user.mobile
                    re_data["token"] = token.decode("utf-8")
                    print(re_data)


            except User.DoesNotExist:
                print("用户不存在")
                self.set_status(400)
                re_data["mobile"] = "用户不存在"

            self.finish(re_data)


class ProfileHandler(RedisHandler):
    @authenticated_async
    async def get(self, *args, **kwargs):
        re_data = {
            "nick_name": self.current_user.nickname,
            "mobile": self.current_user.mobile,
            "gender": self.current_user.gender,
            "address": self.current_user.address,
            "desc": self.current_user.desc,
        }

        self.finish(re_data)



    @authenticated_async
    async def patch(self, *args, **kwargs):
        re_data = {}
        param = self.request.body.decode("utf-8")
        param = json.loads(param)
        form = ProfileForm.from_json(param)
        if form.validate():
            #self.current_user.nickname = form.nickname.data
            self.current_user.gender = form.gender.data
            self.current_user.address = form.address.data
            self.current_user.desc = form.desc.data
            await self.application.objects.update(self.current_user)

        else:
            self.set_status(400)
            for field in form.errors:
                re_data[field] = form.errors[field][0]

        self.finish(re_data)